第5节 函数和作用域大纲
【金山文档】 函数思维导图(复习)
https://kdocs.cn/l/sjIl7tCyXsK6
前言: 完成以下练习
编写代码:计算 1-100 相加并输出结果, 计算 1-200 相加,并输出结果, 计算 1-300 相加,并输出结果
没学函数前, 我们可能会写三遍 for 循环, 有了函数之后只需要写一遍即可.
(一)函数的声明函数的调用
函数就是封装(打包)多行函数, 元素函数就是运行函数封装的多行代码
- 函数声明和调用
- 对象中的函数(方法), alert 就是 window 对象的一个方法
- 函数和变量声明提前
- 函数表达式
(1)函数的声明和调用
- 声明函数 fuction xxx() {}
- 调用函数 xxx(), 函数被调用的时候, 函数体(函数内部的代码)才会运行
- js代码的运行分两步:
- 先解析代码
- 运行代码
- 函数和变量的声明会提前
- 函数是"一等公民", 程序运行的时候, 不管函数定义在什么位置, 都会先执行声明, 所以在任何地方都可以调用函数.
- 变量也会一开始运行就声明, 等到代码运行到变量声明的那句代码才可以对其进行赋值
<script>
// 调用函数
sum();
console.log('ghkjhkhk');
// 声明函数
function sum() {
var count=0;
for(var i=0;i<100;i++) {
count+=i;
}
console.log('count',count);
}
// 调用函数
sum();
</script>
<script>
console.log('str',str); // 不会报错,输出undefined
var str = 'hello';
console.log('str',str); // hello
</script>
(2) 对象中的方法
定义在对象中的函数就是对象的方法, 下面say函数是obj对象的一个方法
alert, console, prompt都是window对象的方法
<script>
var obj = {
name: 'zhangsan',
age: 18,
say: function() {
console.log('它是张三');
}
}
obj.say();
</script>
(3) 函数表达式(先了解)
使用函数表达式来创建函数的时候, 调用函数必须放在函数之后
<script>
// 使用函数表达式时, say在这里还没赋值, 所以它的值就是undefined, 所以不能调用
console.log('say',say);
var say = function () {
console.log('它居然会说话')
};
// 必须在赋值之后去调用(就是在表达式之后才能调用)
say();
</script>
(二)函数的调用方式
(1) 手动调用
(2) 绑定一个事件来触发函数的运行
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width='device-width', initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button onclick="say()">按钮</button>
<script>
function say(){
console.log('哈哈哈哈哈');
}
// 调用函数
say();
</script>
</body>
</html>
// 练习
写一个函数,实现50 到 500 相加, 并输出到网页上
<script> function sum() { var total = 0; for(var i=50;i<=500;i++) { total += i; } document.write(total); } sum(); </script>
需求: 从页面上输入两个加数,绑定事件,计算两个加数相加的结果,并显示在页面上
<!DOCTYPE html> <html lang="en"> <body> <input class="num"> + <input class="num"> <button onclick="add()">=</button> <span id="sum">?</span> <script> function add() { // 获取两个input元素对象 var $inputs = document.querySelectorAll('.num'); // 获取第一个input的值 var num1 = $inputs[0].value; // 获取第二个input的值 var num2 = $inputs[1].value; // 两个加数相加,赋值给sum var sum = num1*1 + num2*1; var $sum = document.querySelector('#sum'); $sum.innerHTML = sum; } </script> </body> </html>
// 代码调试例子 <body> <input class="num" type="text">+<input class="num" type="text"><button onclick="sum()">=</button> <span id="app">?</span> <script> function sum(){ var $num = document.querySelectorAll('.num'); var $num1 = $num[0].value; var $num2 = $num[1].value; var $app = document.querySelector('#app'); $app.innerTxet= $num1*1+ $num2*1; console.log($app) } </script> </body>
(三)函数传递参数(重要)
- 调用函数可以通过()传入任意类型参数, 被调用函数通过()接收参数(demo1)
- 调用时传入什么数据,函数就接收到什么数据
- 传入的参数可以是任何类型
- 传入的参数叫实参, 接收的参数叫形参, 形参和实参位置一一对应
- 基本数据类型和引用数据类型参数的区别(先了解)
<!-- demo1 -->
<!DOCTYPE html>
<html lang="en">
<body>
<script>
function say(a) {
console.log(a);
}
say(100);
say('abcd');
say({name:'zhangsan',age: 100});
</script>
</body>
</html>
<!-- demo2 -->
<!DOCTYPE html>
<html lang="en">
<body>
<script>
var a = 100;
var b = 200;
say(a,b);
function say(x,y) {
console.log(x,y);
}
</script>
</body>
</html>
// 练习:
- 编写一个任意两数相加的函数, 调用函数将结果输出在控制台
- 编写一个累加的函数,用户输入任意两个数都能计算累加的结果, 比如: 用户输入10,20, 则将10~20累加
<!DOCTYPE html>
<html lang="en">
<body>
<script>
// 第1题
function add(a,b) {
var sum = a*1+b*1;
console.log(sum);
}
add(10,20);
add(100,200);
</script>
</body>
</html>
<script>
// 第2题
function sum(x,y) {
var total = 0;
for (var i = x; i <= y; i++) {
total += i;
}
console.log(total);
}
sum(1,100);
sum(15,25);
</script>
(四)函数返回值
4.1 使用 return 返回计算的结果(是否需要返回根据你自己的需要) 4.2 没写 return,默认返回 undefined
<script>
function add(a,b) {
var sum = a+b;
return sum;
}
var sum = add(10,20);
console.log('调用结果',sum);
</script>
<script>
function add(a,b) {
var sum = a+b;
console.log(sum);
}
var sum = add(10,20);
console.log('调用结果',sum); // undefined
</script>
// 练习 练习 4. 需求: 声明一个函数,实现 1 到任意数字累加的结果
(五)作用域
什么是作用域?
答: 变量的作用域指的是变量起作用的领域(范围)就是变量的作用域.
- 作用域和变量
- 作用域访问规则
(1) 作用域和变量
全局作用域和全局变量: 全局作用域就是window,在window下定义的变量就是全局变量
var num = 100; // 全局变量num会自动的变成window的一个属性 window.num2 = 200; console.log(window.num2); consoel.log(num2); // 全局变量可以直接访问, 省略window.
函数运行时, 函数内部就形成了局部作用域, 在函数内部声明的变量就是局部变量
局部变量在函数运行的时候存在, 函数运行结束就被销毁
ps: 区分全局和局部变量的标准就是看这个变量是否是在函数内声明的
<script>
// num是全局变量
var num = 100;
// sum,a,b都是局部变量, 因为它们都是函数add内
function add(a, b) {
var sum = a + b;
return sum;
}
</script>
js没有块级作用域(后台语言有块级作用域, 以{}进行区分)
解释: js的作用域以函数作为区分标准, 而不是以{}作为区分标准
<script> for(var i=0;i<5;i++) { console.log(2222); } console.log(i); </script>
(4) 作用域规则
函数内部可以访问函数外部的变量
函数外部不可以访问函数内部的变量
<script> var x = 100; function aa() { var y = 200; console.log(x); // 里面可以访问外面 } aa(); console.log(y); // 外面无法访问里面 </script>
多个嵌套的作用域形成了作用域链
当访问一个变量时, 从最近的作用域开始查找, 若没有就查找向上一层作用域, 一直到全局作用域为止, 若找到就返回, 找不到就报错"xxx is not defined"
<script> var x = 100; function aa() { var a = 10; function bb() { var b = 20; function cc() { var c = 30; console.log(x); console.log(y); } cc(); } bb(); } aa(); </script>
作业:
使用函数的方式重写电影列表和影院列表页面
编写一个简单计算器(eval 用来计算)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="./style.css"> </head> <body> <div class="box"> <div class="inp-box"> <input id="inp" class="inp" type="text" placeholder="简单计算器"> </div> <ul class="list"> <li>C</li> <li>CE</li> <li>%</li> <li>/</li> <li>7</li> <li>8</li> <li>9</li> <li>x</li> <li>4</li> <li>5</li> <li>6</li> <li>-</li> <li>1</li> <li>2</li> <li>3</li> <li>+</li> <li style="width: 210px;">0</li> <li>.</li> <li>=</li> </ul> </div> </body> </html>
* { margin: 0; padding: 0; } ul, li { list-style: none; } .box { margin-top: 100px; width: 440px; background-color: #ebebeb; margin: 0 auto; padding: 5px; } .inp-box { height: 50px; display: flex; justify-content: center; align-items: center; margin-bottom: 5px; } .inp-box .inp { width: 100%; height: 45px; border: none; text-indent: 20px; font-size: 25px; outline: none; } .list { display: flex; flex-wrap: wrap; justify-content: space-between; } .list li { user-select: none; width: 100px; height: 65px; text-align: center; line-height: 65px; font-size: 20px; background-color: #fff; margin-bottom: 10px; cursor: pointer; }